package com.shjzit.loglib.logservice;

import android.app.ActivityManager;
import android.app.IntentService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;

import com.blankj.utilcode.util.NetworkUtils;
import com.shjzit.loglib.LogUtils;
import com.shjzit.loglib.ParseResult;
import com.shjzit.loglib.db.DatabaseManager;
import com.shjzit.loglib.db.dao.LogDao;
import com.shjzit.loglib.db.dao.LogDaoHelper;
import com.shjzit.loglib.db.entity.LogEntity;
import com.shjzit.loglib.net_http.OkhttpRequestManager;
import com.shjzit.loglib.utils.PrintLog;
import com.shjzit.loglib.utils.ThreadUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;

public class LogUploadService extends IntentService {

    private final long WAIT_TIME = 10 * 1000L;

    private boolean isWorking = false;

    private static class BuildHelp {
        private static final LinkedBlockingDeque<LogEntity> LOGENTITYLINKEDBLOCKINGDEQUE = new LinkedBlockingDeque<>();
    }

    public static LinkedBlockingDeque<LogEntity> getBlockingDeque() {
        return BuildHelp.LOGENTITYLINKEDBLOCKINGDEQUE;
    }

    /**
     * 开启服务
     */
    public static synchronized void startService(Context context) {
        try {
            Intent intent = new Intent(context, LogUploadService.class);
            context.startService(intent);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static boolean isServiceRunning(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (LogUploadService.class.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    public LogUploadService() {
        super("upload_log");

    }

    @Override
    public void onCreate() {
        super.onCreate();
        isWorking = true;
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        super.onStart(intent, startId);
        registerReceiver(receiver, new IntentFilter("com.jzlog.lib"));
        OkhttpRequestManager.getInstance().init(this);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        while (isWorking) {
            try {
                long createAt = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
                deleteOvertimeLogs(createAt);
                LogEntity logEntity = LogDaoHelper.queryFirstLog();
                if (logEntity != null) {
                    uploadLog(logEntity);
                } else {
                    // 用来做线程阻塞,没有消息的时候,等待有消息的时候运行
                    PrintLog.print_e("waiting --> (" + Thread.currentThread().getName() + " )");
                    LogEntity firstLog = getBlockingDeque().take();
                }
            } catch (Exception e) {
                PrintLog.print_e("log 上报出错 ---> " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * 删除早于指定时间的日志
     *
     * @param createAt
     */
    public static void deleteOvertimeLogs(long createAt) {
        try {
            LogDao dao = DatabaseManager.getInstance().getDatabase().logDao();
            while (true) {
                List<LogEntity> logEntities = dao.queryFirstOvertimeLog(createAt);
                if (logEntities == null || logEntities.isEmpty()) {
                    break;
                }
                for (LogEntity entity : logEntities) {
                    dao.deleteLogs(entity);
                    ThreadUtils.sleep(1);
                }

                Log.d("YangKL", "删除数据 -》 删除了 500条");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private synchronized void uploadLog(LogEntity entity) {
        String entityContent = entity.getContent();
        if (TextUtils.isEmpty(entityContent)) {
            return;
        }
        JSONObject params = LogUtils.getInstance().getListener().getParams();
        try {
            params.put("appContent", entityContent);
            if (NetworkUtils.isConnected()) {
                try {
                    LogUtils.getInstance().getListener().onUploadStart(entity.getLogId());
                    String result = OkhttpRequestManager.getInstance().doPost(
                            LogUtils.getInstance().getListener().getHostUrl(),
                            params.toString(),
                            LogUtils.getInstance().getListener().getHeaders(),
                            entity
                    );

                    ParseResult parseResult = LogUtils.getInstance().getListener().parseResp(result);
                    if (parseResult.isSuccess()) {
                        LogUtils.getInstance().deleteLogs(entity);
                        PrintLog.print_i("上传成功 --> logId : " + entity.getLogId());
                    } else {
                        long waitSeconds = parseResult.getWaitSeconds();
                        if (waitSeconds == 0) { // 如果客户端没有给等待时间，那么默认给 1 秒
                            waitSeconds = 1;
                        }
                        PrintLog.print_i("上传失败了,客户端反馈上传失败，并等待" + waitSeconds + "秒");
                        sleep(waitSeconds * 1000);
                    }
                } catch (Exception ex) {
                    ParseResult parseResult = LogUtils.getInstance().getListener().parseError(ex);
                    if (parseResult.isSuccess()) {
                        LogUtils.getInstance().deleteLogs(entity);
                    } else {
                        long waitSeconds = parseResult.getWaitSeconds();
                        if (waitSeconds == 0) { // 如果客户端没有给等待时间，那么默认给 1 秒
                            waitSeconds = 1;
                        }
                        PrintLog.print_i("客户端反馈上传失败，并等待" + waitSeconds + "秒");
                        sleep(waitSeconds * 1000);
                    }
                }
            } else {
                PrintLog.print_i("当前无网络状态!!");
                sleep(WAIT_TIME);
            }
        } catch (JSONException e) {
            LogUtils.getInstance().deleteLogs(entity);
            PrintLog.print_i("构建JSON失败，删除 -- " + entity.getCreateTime());
        }
    }

    private void sleep(long mills) {
        try {
            Thread.sleep(mills);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isWorking = false;
        unregisterReceiver(receiver);
        OkhttpRequestManager.getInstance().cancel(LogUtils.getInstance().getListener().getHostUrl());
        getBlockingDeque().clear();
    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                getBlockingDeque().put(new LogEntity());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    };
}
